package com.springapp.mvc.dao.student;

import com.springapp.mvc.cache.annotation.SmartCache;
import com.springapp.mvc.dao.BaseDao;
import com.springapp.mvc.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * Created by will.lin on 2015/9/15.
 */
@Repository
public class StudentDao implements BaseDao<Student> {

    @Autowired
    private JdbcTemplate jdbcTemplate;


    @Override
    public int save(final Student student) {
        final String sql = "insert into student(name,age,classname) values (?,?,?)";
        int id = jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps =
                        connection.prepareStatement(sql, new String[]{"id"});//返回id
                ps.setString(1, student.getName());
                ps.setInt(2, student.getAge());
                ps.setString(3, student.getClassName());
                return ps;
            }
        });
        return id;

    }

    @Override
    public int update(final Student student) {
        final String sql = "UPDATE  student SET name=? , age=? , classname=? WHERE id=?";
        int id = jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps =
                        connection.prepareStatement(sql, new String[]{"id"});//返回id
                ps.setString(1, student.getName());
                ps.setInt(2, student.getAge());
                ps.setString(3, student.getClassName());
                ps.setLong(4,student.getId());
                return ps;
            }
        });
        return id;

    }

    @SmartCache(cacheName = "student")
    @Override
    public Student find(int id) {
        Student student = (Student) this.jdbcTemplate.queryForObject(
                "select id,name,age,classname from student where id = ?",
                new Object[]{new Long(id)},
                new RowMapper(){

                    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
                        Student act = new Student();
                        act.setId(rs.getInt("id"));
                        act.setName(rs.getString("name"));
                        act.setAge(rs.getInt("age"));
                        act.setClassName(rs.getString("classname"));
                        return act;
                    }

                });
        return student;
    }

    @Override
    public int delete(final int id) {
        final String sql = "DELETE FROM student WHERE id=?";
        int uid = jdbcTemplate.update(new PreparedStatementCreator() {
            @Override
            public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                PreparedStatement ps =
                        connection.prepareStatement(sql, new String[]{"id"});//返回id
                ps.setLong(1, id);
                return ps;
            }
        });
        return uid;

    }

    @Override
    public List<Student> findAll() {
        String sql="select id,name,age,classname from student";
        return jdbcTemplate.query(sql, new StudentMapper());
    }


    /**
     * 定义一个静态内部类，在Dao的方法中被共享
     * @author logcd
     */
    private static final class StudentMapper implements RowMapper{

        public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
            Student act = new Student();
            act.setId(rs.getInt("id"));
            act.setName(rs.getString("name"));
            act.setAge(rs.getInt("age"));
            act.setClassName(rs.getString("classname"));
            return act;
        }

    }
}
